package me.leon.aop;

import android.util.Log;
import android.view.View;

import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.Around;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Pointcut;
import org.aspectj.lang.reflect.MethodSignature;

import java.lang.reflect.Method;
import java.util.concurrent.TimeUnit;

/**
 * <p>description：</p>
 * <p>author：Leon</p>
 * <p>date：2019/8/29 0029</p>
 * <p>e-mail：deadogone@gmail.com</p>
 */
@Aspect
public class LeonAop {
    /**
     * 最近一次点击的时间
     */
    private static long mLastClickTime;
    /**
     * 最近一次点击的控件ID
     */
    private static int mLastClickViewId;

    @Pointcut("execution(* me.leon.aop.*.aop*(..))")
    public void debugLog() {
    }

    @Pointcut("execution(* me.leon.aop.MyLog.*(..))")
    public void sout() {
    }

    @Pointcut("execution(@me.leon.aop.SingleClick * *(..))")
    public void clickFilter() {
    }

    @Around("debugLog()")
    public Object log(ProceedingJoinPoint joinPoint) throws Throwable {
        long startNanos = System.nanoTime();
        //执行原方法
        Object result = joinPoint.proceed();
        long stopNanos = System.nanoTime();
        long lengthMillis = TimeUnit.NANOSECONDS.toMillis(stopNanos - startNanos);
        Log.d("AOP", joinPoint.getSignature().getName() + lengthMillis);
        return result;
    }

    @Around("sout()")
    public Object println(ProceedingJoinPoint joinPoint) throws Throwable {
        //执行原方法
        Object result = joinPoint.proceed();
        Log.d("AOP", joinPoint.getSignature().getName());
        return result;
    }

    @Around("clickFilter()")
    public void injectClick(ProceedingJoinPoint joinPoint) throws Throwable {
// 取出方法的参数
        View view = null;
        for (Object arg : joinPoint.getArgs()) {
            if (arg instanceof View) {
                view = (View) arg;
                break;
            }
        }
        if (view == null) {
            return;
        }

        MethodSignature methodSignature = (MethodSignature) joinPoint.getSignature();
        Method method = methodSignature.getMethod();
        if (!method.isAnnotationPresent(SingleClick.class)) {
            return;
        }
        SingleClick singleClick = method.getAnnotation(SingleClick.class);
        // 判断是否快速点击
        if (!isFastDoubleClick(view, singleClick.value())) {
            // 不是快速点击，执行原方法
            joinPoint.proceed();
        }else {
            Log.d("AOP", "快速 click 过滤 : " + joinPoint.getSignature().getName());
            return;
        }
        Log.d("AOP", "click : " + joinPoint.getSignature().getName());
    }

    /**
     * 是否是快速点击
     *
     * @param v              点击的控件
     * @param intervalMillis 时间间期（毫秒）
     * @return true:是，false:不是
     */
    public boolean isFastDoubleClick(View v, long intervalMillis) {
        int viewId = v.getId();
        long time = System.currentTimeMillis();
        long timeInterval = Math.abs(time - mLastClickTime);
        if (timeInterval < intervalMillis && viewId == mLastClickViewId) {
            return true;
        } else {
            mLastClickTime = time;
            mLastClickViewId = viewId;
            return false;
        }
    }

}
